package bairui.international.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.lianjing.sh.project.common.service.Service_Number;
import com.lianjing.sh.validate.spring.exception.ValidateObjectException;
import com.sh_lianjing.state.StateTransition;

import bairui.international.common.config.Config_Setup;
import bairui.international.model.domain.jpa.TB_BranchCompany;
import bairui.international.model.domain.jpa.TB_BranchCompanyStaff;
import bairui.international.model.domain.jpa.TB_BranchCompanyStaffRoyaltyRecord;
import bairui.international.model.domain.jpa.TB_ElectronicTicket;
import bairui.international.model.domain.jpa.TB_GoodsInfo;
import bairui.international.model.domain.jpa.TB_Product;
import bairui.international.model.domain.jpa.TB_ProductOrder;
import bairui.international.model.domain.jpa.TB_ProductOrderItem;
import bairui.international.model.domain.jpa.TB_Town;
import bairui.international.model.domain.jpa.TB_User;
import bairui.international.model.domain.jpa.TB_UserAmount;
import bairui.international.model.domain.jpa.TB_UserInfo;
import bairui.international.model.status.State_ProductOrder;
import bairui.international.model.type.Type_ProductOrder;
import bairui.international.model.type.Type_ProductOrderPay;
import bairui.international.service.Service_Address;
import bairui.international.service.Service_BranchCompany;
import bairui.international.service.Service_BranchCompanyMoneyRecord;
import bairui.international.service.Service_BranchCompanyStaff;
import bairui.international.service.Service_BranchCompanyStaffMoneyRecord;
import bairui.international.service.Service_BranchCompanyStaffRoyaltyRecord;
import bairui.international.service.Service_ElectronicTicket;
import bairui.international.service.Service_GoodsInfo;
import bairui.international.service.Service_Product;
import bairui.international.service.Service_ProductOrder;
import bairui.international.service.Service_ProductOrderItem;
import bairui.international.service.Service_ProductOrderStateRecord;
import bairui.international.service.Service_Town;
import bairui.international.service.Service_User;
import bairui.international.service.Service_UserAmount;
import bairui.international.service.Service_UserGradeRecord;
import bairui.international.service.Service_UserInfo;

/**
 * 
 * 【(产品订单)TB_ProductOrder】服务实现
 *
 * @generated
 * 
 * @see bairui.international.model.domain.jpa.产品订单.TB_ProductOrder 模型
 * @see Service_ProductOrder 服务接口
 * @see BService_ProductOrderImpl 服务实现基础
 *
 */
@Service
public class Service_ProductOrderImpl extends BService_ProductOrderImpl implements Service_ProductOrder {

	@Autowired private Service_Number service_Number;
	@Autowired private Service_GoodsInfo service_GoodsInfo;
	@Autowired private Service_UserInfo service_UserInfo;
	@Autowired private Service_User service_User;
	@Autowired private Service_ProductOrderStateRecord service_ProductOrderStateRecord;
	@Autowired private Service_Product service_Product;
//	@Autowired private Service_SystemConfig service_SystemConfig;
	@Autowired private Service_BranchCompanyStaffRoyaltyRecord service_BranchCompanyStaffRoyaltyRecord;
	@Autowired private Service_UserAmount service_UserAmount;
	@Autowired private Service_UserGradeRecord service_UserGradeRecord;
	@Autowired private Service_Address service_Address;
	@Autowired private Service_ElectronicTicket service_ElectronicTicket;
//	@Autowired private Service_ProductPropertyItem service_ProductPropertyItem;
	@Autowired private Service_Town service_Town;
	@Autowired private Service_BranchCompany service_BranchCompany;
	@Autowired private Service_BranchCompanyStaff service_BranchCompanyStaff;
	@Autowired private Service_ProductOrderItem service_ProductOrderItem;
	@Autowired private Service_BranchCompanyMoneyRecord service_BranchCompanyMoneyRecord;
	@Autowired private Service_BranchCompanyStaffMoneyRecord service_BranchCompanyStaffMoneyRecord;
	
	private TB_ProductOrder createInstance(
		TB_User user, Double price, Double score, Type_ProductOrder type, String imgUrl
	){
		TB_ProductOrder order = new TB_ProductOrder(
				new TB_ProductOrder.MustProperties() {
					@Override public TB_User getUser() {
						return user;
					}
					@Override public State_ProductOrder getState() {
						return State_ProductOrder.t_create().to();
					}
					@Override public Double getPrice() {
						return price;
					}
					@Override public String getNumber() {
						return service_Number.generateDateFormatNumber("ProductOrderNumber");
					}
					@Override public Double getScore() {
						return score;
					}
					@Override public Type_ProductOrder getType() {
						return type;
					}
					@Override public Boolean getAssignFlag() {
						return false;
					}
				},
				new TB_ProductOrder.OptionalSingleProperties() {
					@Override public TB_Town getArea() {
						return null;
					}
					@Override public String getAreaRecord() {
						return null;
					}
					@Override public TB_UserInfo getUserInfo() {
						return null;
					}
					@Override public Double getUsedScore() {
						return null;
					}
					@Override public Date getSubmitDate() {
						return null;
					}
					@Override public Type_ProductOrderPay getPayWay() {
						return null;
					}
					@Override public Double getPay() {
						return null;
					}
					@Override public String getImgUrl() {
						return imgUrl;
					}
					@Override public TB_GoodsInfo getGoodsInfo() {
						return null;
					}
					@Override public String getRemitImgUrl() {
						return null;
					}
					@Override public TB_ElectronicTicket getElectronicTicket() {
						return null;
					}
					@Override public String getComment() {
						return null;
					}
					@Override public TB_BranchCompany getBranchCompany() {
						return null;
					}
					@Override public TB_BranchCompanyStaff getAssignor() {
						return null;
					}
					@Override public TB_BranchCompanyStaff getSender() {
						return null;
					}
				}
			);
		return dao.save(order);
	}
	
	/**
	 * 创建积分兑换订单
	 * @throws ValidateObjectException 
	 */
	@Override
	public TB_ProductOrder createGradeOrder(
		TB_User user, List<InputForCreate> products
	) throws ValidateObjectException{
		/* 创建订单 */
		TB_ProductOrder order = createInstance(user, 0D, 0D, Type_ProductOrder.Grade, null);
		/* 创建订单项 */
		BigDecimal score = BigDecimal.ZERO;
		TB_ProductOrderItem firstProductOrderItem = null;
		for(InputForCreate input : products){
			TB_Product product = service_Product.load(input.getProduct());
			// 创建订单项
			TB_ProductOrderItem productOrderItem = null;
			productOrderItem = service_ProductOrderItem.createForGrade(product, order, input.getAmount());
			//
			if(null == firstProductOrderItem){
				firstProductOrderItem = productOrderItem;
			}
			// 计算积分
			score = score.add(BigDecimal.valueOf(productOrderItem.getProductTotalScore()));
		}
		/* 更新订单数据 */
		order.setScore(score.doubleValue());
		order.setImgUrl(firstProductOrderItem.getProductImgUrl());
		/*
		 * 扣除积分
		 */
		TB_UserAmount grade = user.getUserAmount();
		if(null == grade){
			throw new ValidateObjectException("object", "", "积分不足");
		}else{
			Double subScore = BigDecimal.valueOf(grade.getGrade())
					.subtract(score)
					.doubleValue();
			if(subScore < 0){
				throw new ValidateObjectException("object", "", "积分不足");
			}
			//
			grade = service_UserAmount.findByIdUseLock(grade.getId());
			grade.setGrade(subScore);
			// 创建积分记录
			service_UserGradeRecord.createScoreRecord(user, score.doubleValue(), subScore, order);
		}
//		/* 创建订单用户信息 */
//		service_UserInfo.createInstance(order, user.getType(), user.getNickName(), user.getRealName(), user.getCompany());
//		/* 创建订单记录 */
//		service_ProductOrderStateRecord.createFlowRecord(order, State_ProductOrder.t_create().comment());
		return order;
	}
	
	@Override
	public void cancelOrder(long id) throws Exception {
		TB_ProductOrder order = findById(id);
		// 更新信息
		StateTransition<State_ProductOrder> trans = order.new UpdateProperties() {
			StateTransition<State_ProductOrder> trans;
			@Override public State_ProductOrder getState(TB_ProductOrder it) throws Exception {
				trans = it.getState().t_cancel_to_Canceled();
				return trans.to();
			};
		}.trans;
		// 记录
		service_ProductOrderStateRecord.createFlowRecord(order, trans.comment());
	}
	
	@Override
	public void cancelGradeOrder(long id) throws Exception {
		/*
		 * 取消订单
		 */
		TB_ProductOrder order = cancel(id);
		/*
		 * 返回积分
		 */
		TB_User user = order.getUser();
		TB_UserAmount userAmount = service_UserAmount.findByIdUseLock(user.getUserAmount().getId());
		Double grade = BigDecimal.valueOf(userAmount.getGrade())
				.add(BigDecimal.valueOf(order.getScore()))
				.doubleValue();
		userAmount.setGrade(grade);
		// 创建积分记录
		service_UserGradeRecord.createScoreRecord(user, -order.getScore(), grade, order);
	}
	
	@Override
	public TB_ProductOrder create(
		TB_User user, 
		List<InputForCreate> inputs
	) throws Exception {
		user = service_User.load(user);
		/* 创建订单 */
		TB_ProductOrder order = createInstance(user, 0D, 0D, Type_ProductOrder.Buy, null);
		/* 创建订单项 */
		BigDecimal price = BigDecimal.ZERO;
		TB_ProductOrderItem firstProductOrderItem = null;
		for(InputForCreate input : inputs){
			TB_Product product = service_Product.load(input.getProduct());
			// 创建订单项
			TB_ProductOrderItem productOrderItem = null;
			if(product.getRootCategory().getName().equals(Config_Setup.Wrap)){
				productOrderItem = service_ProductOrderItem.createForPack(product, order, input.getAmount());
			}else{
				productOrderItem = service_ProductOrderItem.createForProduct(product, order, input.getAmount());
			}
			//
			if(null == firstProductOrderItem){
				firstProductOrderItem = productOrderItem;
			}
			// 计算价格
			price = price.add(BigDecimal.valueOf(productOrderItem.getProductTotalPrice()));
		}
		/* 更新订单数据 */
		order.setPrice(price.doubleValue());
		order.setImgUrl(firstProductOrderItem.getProductImgUrl());
		/* 创建订单用户信息 */
		service_UserInfo.createInstance(order, user.getType(), user.getNickName(), user.getRealName(), user.getCompany());
		/* 创建订单记录 */
		service_ProductOrderStateRecord.createFlowRecord(order, State_ProductOrder.t_create().comment());
		//
		return order;
	}
	
	/**
	 * 按区域分配订单到分公司
	 */
	private void assignToBranchCompany(TB_ProductOrder order, TB_Town town){
		TB_BranchCompany branchCompany = service_BranchCompany.findOne(it->it.area.contains(town));
		if(null != branchCompany){
			branchCompany.addProductOrders(order);
		}
	}
	
	/**
	 * 设置订单信息
	 */
	@Override
	public void setOrderInfo(TB_ProductOrder order, TB_Town town, String username, String phone, String address, String orderComment) throws Exception{
		order = load(order);
		town = service_Town.load(town);
		order.setArea(town);
		order.setComment(orderComment);
		/* 创建订单相关信息 */
		String fixAddress = town.getCity().getProvince().getName() + "/" + town.getCity().getName() + "/" + town.getName();
		TB_GoodsInfo info = order.getGoodsInfo();
		if(null != info){
			order.setGoodsInfo(null);
			info.setProductOrder(null);
			service_GoodsInfo.delete(info.getId());
			dao.getEntityManager().flush();
		}
		service_GoodsInfo.createInstance(order, address, fixAddress, username, phone);
		// 处理地址
		this.dealAddress(order.getUser(), town, username, phone, address);
	}
	
	/**
	 * 处理地址
	 */
	private void dealAddress(TB_User user, TB_Town town, String username, String phone, String address){
		if(!service_Address.exists(it->
				it.user.eq(user)
				.and(it.name.eq(username.trim()))
				.and(it.townId.eq(town.getId()))
				.and(it.phone.eq(phone.trim()))
				.and(it.detailAddress.eq(address.trim()))
			)
		){
			service_Address.add(user, username, phone, town, address, false);
		}
	}
	
	/**
	 * 在线支付
	 */
	@Override
	public TB_ProductOrder onLinePay(String orderNumber) throws Exception {
		TB_ProductOrder order = findOne(it->it.number.eq(orderNumber.trim()));
		// 更新信息
		StateTransition<State_ProductOrder> trans = order.new UpdateProperties() {
			StateTransition<State_ProductOrder> trans;
			@Override public State_ProductOrder getState(TB_ProductOrder it) throws Exception {
//				trans = it.getState().t_pay_from_Paying();
				trans = it.getState().t_payProduct_from_Paying();
				return trans.to();
			};
			@Override public Date getSubmitDate(TB_ProductOrder it) throws Exception {
				return new Date();
			};
			@Override public Type_ProductOrderPay getPayWay(TB_ProductOrder it) throws Exception {
				return Type_ProductOrderPay.OnLine;
			};
		}.trans;
		// 记录
		service_ProductOrderStateRecord.createFlowRecord(order, trans.comment());
		// 处理优惠券
		TB_ElectronicTicket ticket = order.getElectronicTicket();
		if(null != ticket){
			service_ElectronicTicket.use(ticket.getId(), order);
		}
		// 按区域分配订单到分公司
		this.assignToBranchCompany(order, order.getArea());
		// 如果用户有配送关系则自动分配
		this.assignToSender(order);
		//
		return order;
	}
	
	/**
	 * 如果用户有配送关系则自动分配
	 */
	private void assignToSender(TB_ProductOrder order) throws Exception{
		TB_BranchCompanyStaff sender = order.getUser().getSender();
		if(null != sender && sender.getBranchCompany().equals(order.getBranchCompany())){
			order.new UpdateProperties() {
				@Override public TB_BranchCompanyStaff getSender(TB_ProductOrder it) throws Exception {
					return sender;
				};
			};
		}
	}
	
	/**
	 * 累积处理积分
	 */
	private void dealScore_add(TB_ProductOrder order){
		BigDecimal score = BigDecimal.ZERO;
		for(TB_ProductOrderItem orderItem : order.getProductOrderItems()){
			TB_Product product = orderItem.getProduct();
//			score = score.add(
//						BigDecimal
//							.valueOf(orderItem.getProductTotalPrice())
//							.multiply(BigDecimal.valueOf(product.getExchangeRate()))
//							.divide(BigDecimal.valueOf(100D))
//					);
			score = score.add(
					BigDecimal
						.valueOf(orderItem.getAmount())
						.multiply(BigDecimal.valueOf(product.getExchange()))
				);
		}
		if(0 == score.doubleValue()){
			return;
		}
		//
		TB_User user = order.getUser();
		TB_UserAmount grade = user.getUserAmount();
		Double currentScore = 0d;
		if(null == grade){
			grade = service_UserAmount.createInstance(user, score.doubleValue());
			currentScore = score.doubleValue();
		}else{
			grade = service_UserAmount.findByIdUseLock(grade.getId());
			currentScore = BigDecimal.valueOf(grade.getGrade())
					.add(score)
					.doubleValue();
			grade.setGrade(currentScore);
		}
		// 创建积分记录
		service_UserGradeRecord.createOrderBuyRecord(user, score.doubleValue(), currentScore, order);
	}
	
	private void separateAccount(TB_ProductOrder order){
		TB_BranchCompanyStaff divider = order.getSender();
		// 处理分成
		for(TB_ProductOrderItem orderItem : order.getProductOrderItems()){
			TB_Product product = orderItem.getProduct();
			if(0 == product.getDivideRate()){
				return;
			}
			double money = BigDecimal
					.valueOf(orderItem.getProductTotalPrice())
					.multiply(BigDecimal.valueOf(product.getDivideRate()))
					.divide(BigDecimal.valueOf(100D))
					.doubleValue();
			// 配送者提成记录
			TB_BranchCompanyStaffRoyaltyRecord userRoyaltyRecord = service_BranchCompanyStaffRoyaltyRecord.createInstance(divider, orderItem, order, money, product.getDivideRate());
			// 配送者金额记录
			service_BranchCompanyStaffMoneyRecord.create(userRoyaltyRecord);
		}
	}

	@Override
	public TB_ProductOrder send(long id) throws Exception {
		TB_ProductOrder order = findById(id);
		// 更新信息
		StateTransition<State_ProductOrder> trans = order.new UpdateProperties() {
			StateTransition<State_ProductOrder> trans;
			@Override public State_ProductOrder getState(TB_ProductOrder it) throws Exception {
				trans = it.getState().t_send_from_Sending();
				return trans.to();
			};
		}.trans;
		// 记录
		service_ProductOrderStateRecord.createFlowRecord(order, trans.comment());
		//
		return order;
	}

	@Override
	public TB_ProductOrder cancel(long id) throws Exception {
		TB_ProductOrder order = findById(id);
		// 更新信息
		StateTransition<State_ProductOrder> trans = order.new UpdateProperties() {
			StateTransition<State_ProductOrder> trans;
			@Override public State_ProductOrder getState(TB_ProductOrder it) throws Exception {
				trans = it.getState().t_cancel_to_Canceled();
				return trans.to();
			};
		}.trans;
		// 记录
		service_ProductOrderStateRecord.createFlowRecord(order, trans.comment());
		//
		return order;
	}
	
	@Override
	public TB_ProductOrder terminal(long id) throws Exception {
		TB_ProductOrder order = findById(id);
		// 更新信息
		StateTransition<State_ProductOrder> trans = order.new UpdateProperties() {
			StateTransition<State_ProductOrder> trans;
			@Override public State_ProductOrder getState(TB_ProductOrder it) throws Exception {
				trans = it.getState().t_terminal_from_Sending();
				return trans.to();
			};
		}.trans;
		// 记录
		service_ProductOrderStateRecord.createFlowRecord(order, trans.comment());
		//
		return order;
	}
	
	@Override
	public void payUnderLine(
		Double score,
		long orderId,
		Long ticketId,
		TB_Town town, String username, String phone, String address, String orderComment
	) throws Exception {
		/* 处理订单 */
		TB_ProductOrder order = findById(orderId);
		// 计算订单总额
		double orderTotalPrice = order.getPrice();
		// 处理电子券
		Double ticketPrice = 0D;
		if(null != ticketId){
			TB_ElectronicTicket ticket  = service_ElectronicTicket.load(new TB_ElectronicTicket(ticketId));
			ticketPrice = ticket.getElectronicTicketOrder().getPrice();
			ticket.new UpdateProperties() {
				@Override public TB_ProductOrder getProductOrder(TB_ElectronicTicket it) throws Exception {
					return order;
				}
			};
		}
		// 实际付款金额
		if(score > orderTotalPrice - ticketPrice){
			score = orderTotalPrice - ticketPrice;
		}
		double _score = score;
		// 更新信息
		StateTransition<State_ProductOrder> trans = order.new UpdateProperties() {
			StateTransition<State_ProductOrder> trans;
			@Override public State_ProductOrder getState(TB_ProductOrder it) throws Exception {
//				trans = it.getState().t_pay_from_Paying();
				trans = it.getState().t_payProduct_from_Paying();
				return trans.to();
			};
			@Override public Date getSubmitDate(TB_ProductOrder it) throws Exception {
				return new Date();
			};
			@Override public Double getUsedScore(TB_ProductOrder it) throws Exception {
				return _score;
			}
			@Override public Double getPay(TB_ProductOrder it) throws Exception {
				return 0D;
			}
			@Override public Type_ProductOrderPay getPayWay(TB_ProductOrder it) throws Exception {
				return Type_ProductOrderPay.Goods;
			};
		}.trans;
		// 记录
		service_ProductOrderStateRecord.createFlowRecord(order, trans.comment());
		// 设置订单信息
		this.setOrderInfo(order, town, username, phone, address, orderComment);
		// 按区域分配订单到分公司
		this.assignToBranchCompany(order, order.getArea());
		// 如果用户有配送关系则自动分配
		this.assignToSender(order);
		// 处理地址
		this.dealAddress(order.getUser(), town, username, phone, address);
	}

	private void finish(long id, StateTransition<State_ProductOrder> _trans) throws Exception{
		/* 处理订单 */
		TB_ProductOrder order = findById(id);
		// 计算订单总额
		double orderTotalPrice = order.getPrice();
		TB_ElectronicTicket ticket = order.getElectronicTicket();
		Double ticketPrice = 0D;
		if(null != ticket){
			ticketPrice = ticket.getElectronicTicketOrder().getPrice();
		}
		double pay = BigDecimal.valueOf(orderTotalPrice)
			.subtract(BigDecimal.valueOf(order.getScore()))
			.subtract(BigDecimal.valueOf(ticketPrice))
			.doubleValue();
		// 更新信息
		StateTransition<State_ProductOrder> trans = order.new UpdateProperties() {
			StateTransition<State_ProductOrder> trans;
			@Override public State_ProductOrder getState(TB_ProductOrder it) throws Exception {
				trans = _trans;
				return trans.to();
			};
			@Override public Double getPay(TB_ProductOrder it) throws Exception {
				return pay;
			}
		}.trans;
		// 记录
		service_ProductOrderStateRecord.createFlowRecord(order, trans.comment());
		// 处理优惠券
		if(null != ticket){
			service_ElectronicTicket.use(ticket.getId(), order);
		}
		// 分配提成
		if(order.getType() == Type_ProductOrder.Buy){
			// 处理分账
			separateAccount(order);
			// 处理积分
			dealScore_add(order);
			// 设置总金额
			service_BranchCompanyMoneyRecord.create(order);
		}
	}
	
	@Override
	public TB_ProductOrder setScore(long id, Double score, TB_ElectronicTicket ticket) throws Exception {
		TB_ProductOrder order = findById(id);
		// 计算订单总额
		double orderTotalPrice = order.getPrice();
		// 处理电子券
		Double ticketPrice = 0D;
		if(null != ticket){
			ticket  = service_ElectronicTicket.load(ticket);
			ticketPrice = ticket.getElectronicTicketOrder().getPrice();
			ticket.new UpdateProperties() {
				@Override public TB_ProductOrder getProductOrder(TB_ElectronicTicket it) throws Exception {
					return order;
				}
			};
		}
		// 实际付款
		if(score > orderTotalPrice - ticketPrice){
			score = orderTotalPrice - ticketPrice;
		}
		double _score = score;
		double pay = BigDecimal.valueOf(orderTotalPrice)
			.subtract(BigDecimal.valueOf(_score))
			.subtract(BigDecimal.valueOf(ticketPrice))
			.doubleValue();
		// 更新信息
		order.new UpdateProperties() {
			@Override public Double getUsedScore(TB_ProductOrder it) throws Exception {
				return _score;
			}
			@Override public Double getPay(TB_ProductOrder it) throws Exception {
				return pay;
			}
		};
		return order;
	}

	@Override
	public TB_ProductOrder gradeOrderPay(String skey, long id, String username, String phone, String area, String detailAddress, Long townId, String comment) throws Exception {
		TB_User user = service_User.findOne(it->it.skey.eq(skey));
		// 处理地址
		if(!service_Address.exists(skey)){
			service_Address.add(user, username, phone, new TB_Town(townId), detailAddress, true);
		}
		// 处理订单
		TB_ProductOrder bean = findById(id);
		StateTransition<State_ProductOrder> trans = bean.new UpdateProperties() {
			StateTransition<State_ProductOrder> trans;
			@Override public State_ProductOrder getState(TB_ProductOrder it) throws Exception {
//				trans = it.getState().t_submit_from_Paying();
				trans = it.getState().t_payGrade_from_Paying();
				return trans.to();
			};
			@Override public Date getSubmitDate(TB_ProductOrder it) throws Exception {
				return new Date();
			};
			@Override public String getComment(TB_ProductOrder it) throws Exception {
				return comment;
			};
		}.trans;
//		// 处理订单信息
//		service_GoodsInfo.createInstance(bean, detailAddress, area, username, phone);
		service_UserInfo.createInstance(bean, user.getType(), user.getNickName(), user.getRealName(), user.getCompany());
		// 记录
		service_ProductOrderStateRecord.createFlowRecord(bean, trans.comment());
		// 设置订单信息
		this.setOrderInfo(bean, new TB_Town(townId), username, phone, detailAddress, comment);
		// 按区域分配订单到分公司
		this.assignToBranchCompany(bean, bean.getArea());
		//
		return bean;
	}
	
	@Override
	public void setRemitImgUrl(long id, String remitImgUrl) {
		findById(id).setRemitImgUrl(remitImgUrl);
	}

	@Override
	public List<TB_ProductOrder> listExpireTaskOrder() {
		return list(
					it->it.state.eq(State_ProductOrder.Paying).and(it.type.eq(Type_ProductOrder.Buy))
				);
	}

	@Override
	public void assign(long id, String skey, TB_BranchCompanyStaff branchCompanyStaff) throws Exception {
		TB_User user = this.service_User.findOne(it->it.skey.eq(skey));
		TB_BranchCompanyStaff assignor = this.service_BranchCompanyStaff.getActive(user);
		// 指派
		TB_ProductOrder order = findById(id);
		order.new UpdateProperties() {
		 	@Override public TB_BranchCompanyStaff getAssignor(TB_ProductOrder it) throws Exception {
				return assignor;
			};
			@Override public TB_BranchCompanyStaff getSender(TB_ProductOrder it) throws Exception {
				return branchCompanyStaff;
			};
		};
		// 订单发货
		this.send(id);
	}

	@Override
	public void assignBranchCompany(long id, TB_BranchCompany branchCompany) throws Exception {
		TB_ProductOrder bean = findById(id);
		bean.new UpdateProperties() {
			@Override public TB_BranchCompany getBranchCompany(TB_ProductOrder it) throws Exception {
				return branchCompany;
			}
		};
	}

	@Override
	public void submitVerify(long id) throws Exception {
		TB_ProductOrder order = findById(id);
		// 更新信息
		StateTransition<State_ProductOrder> trans = order.new UpdateProperties() {
			StateTransition<State_ProductOrder> trans;
			@Override public State_ProductOrder getState(TB_ProductOrder it) throws Exception {
//				trans = it.getState().t_submitVerify_from_Sended();
				trans = it.getState().t_dealGoods_from_Sended();
				return trans.to();
			};
		}.trans;
		// 记录
		service_ProductOrderStateRecord.createFlowRecord(order, trans.comment());
	}

	@Override
	public void verifyPass(long id) throws Exception {
		TB_ProductOrder order = findById(id);
		this.finish(id, order.getState().t_verifyPass_from_Verifing());
	}
	
	@Override
	public void finish(long id) throws Exception {
		TB_ProductOrder order = findById(id);
		this.finish(id, order.getState().t_dealOnline_from_Sended());
	}

	@Override
	public TB_ProductOrder vertifyGradeOrderPass(long id) throws Exception {
		TB_ProductOrder order = findById(id);
		// 更新信息
		StateTransition<State_ProductOrder> trans = order.new UpdateProperties() {
			StateTransition<State_ProductOrder> trans;
			@Override public State_ProductOrder getState(TB_ProductOrder it) throws Exception {
				trans = it.getState().t_verifyPass_from_Verifing();
				return trans.to();
			};
		}.trans;
		// 记录
		service_ProductOrderStateRecord.createPassRecord(order, trans.comment(), "");
		//
		return order;
	}

	@Override
	public TB_ProductOrder vertifyGradeOrderNoPass(long id, String message) throws Exception {
		TB_ProductOrder order = findById(id);
		// 更新信息
		StateTransition<State_ProductOrder> trans = order.new UpdateProperties() {
			StateTransition<State_ProductOrder> trans;
			@Override public State_ProductOrder getState(TB_ProductOrder it) throws Exception {
				trans = it.getState().t_verifyNoPass_from_Verifing();
				return trans.to();
			};
		}.trans;
		// 记录
		service_ProductOrderStateRecord.createNoPassRecord(order, trans.comment(), message);
		/*
		 * 退还积分
		 */
		TB_User user = order.getUser();
		TB_UserAmount grade = user.getUserAmount();
		Double returnScore = BigDecimal.valueOf(grade.getGrade())
				.add(BigDecimal.valueOf(order.getScore()))
				.doubleValue();
		//
		grade = service_UserAmount.findByIdUseLock(grade.getId());
		grade.setGrade(returnScore);
		// 创建积分记录
		service_UserGradeRecord.createScoreRecord(user, -order.getScore(), returnScore, order);
		//
		return order;
	}
	
}
